package com.example.util;

import com.example.annotation.ConvertSame;
import com.example.entity.Entity;
import com.example.entity.EntityDto;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SpringBeanUtil {

    public static void main(String[] args) {
        Entity outer = new Entity();
        outer.setName("outer");
        Entity inner = new Entity();
        inner.setName("inner");
        //outer.setTher(inner);
        /*
        如果entity和dto里面的myself都是自己类的属性，咋不会转化
        方法1：手动控制，知道自己里面是什么属性的话，就用手动代码转化
         */
        EntityDto dto = new EntityDto();
        convert(outer,dto);
       // BeanUtils.copyProperties(outer,dto);
        //如何将下列代码变成迭代？？
//        if (null!=outer.getMyself())
//        {
//            EntityDto another = new EntityDto();
//            BeanUtils.copyProperties(outer.getMyself(),another);
//            dto.setMyself(another);
//        }
        System.out.println(dto);
    }
    private static void convert(Object outer, Object dto) {
        /*
        扩展点：如果是一个list？
        能否用泛型加注解实现（通过反射机制）
         */
        //if (null ==outer) return;穿过来的outer不能为null
        Class clasz= outer.getClass();
        Field[] fields = clasz.getDeclaredFields();//getFields只能获取public的成员属性，切记
        for (Field field:fields)
        {
            if (null!=field.getAnnotation(ConvertSame.class))
            {
                field.setAccessible(true);
                try {
                    if (null==field.get(outer))
                    {
                        BeanUtils.copyProperties(outer,dto);
                        return;
                    }
                    Object another = new EntityDto();
                    BeanUtils.copyProperties(outer,dto);
                    convert( field.get(outer),another);

                    //通过反射和注解设置entity
                    Class<?> to = dto.getClass();
                    Method[] mymethods = to.getDeclaredMethods();
                    for (Method me: mymethods)
                    {
                        if (null!=me.getAnnotation(ConvertSame.class))
                        {
                            try {
                                me.invoke(dto,another);
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                                System.out.println("反射失败");
                            }
                        }
                    }
                    //dto.setMyself(another);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    System.out.println("field.get(object) 失败");
                }
            }
        }
//        if (null==outer.getMyself())
//        {
//            BeanUtils.copyProperties(outer,dto);
//            return;
//        }
    }
}
